﻿using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using ST.Buz.Base;
using ST.Buz.Base.Entity;
using ST.Buz.Service;
using ST.Common.Util;
using ST.Common.Util.Logging;
using ST.Common.Util.Mvc;
using System;
using System.IO;
using System.Text.Encodings.Web;
using System.Text.Unicode;

namespace ST.Buz.Web
{
	public class Startup
	{
		public Startup(IConfiguration configuration)
		{
			Configuration = configuration;
		}

		public IConfiguration Configuration { get; }

		public void ConfigureServices(IServiceCollection services)
		{
			try
			{
				//logger.LogInformation("ConfigureServices");//todo:日志没有打印出来

				//services.Configure<FormOptions>(x =>
				//{
				//	x.ValueLengthLimit = 2147483647;
				//	x.MultipartBodyLengthLimit = 2147483647;//int.MaxValue;
				//});

				////Cookie策略
				//services.Configure<CookiePolicyOptions>(options =>
				//{
				//	// This lambda determines whether user consent for non-essential cookies is needed for a given request.
				//	options.CheckConsentNeeded = context => true;
				//	options.MinimumSameSitePolicy = SameSiteMode.None;
				//});

				string connStrBuz = Configuration.GetConnectionString("BuzConnection");
				services.AddDbContext<BuzContext>(options => options.UseSqlServer(connStrBuz, opts =>
				{
					//opts.UseRowNumberForPaging();//不再支持ROW_NUMBER()分页方式
				})
				//.AddInterceptors(new MyDbCommandInterceptor()
				);

				#region 添加静态类
				services.AddSingleton<ST.WX.Common.WXBaseApi>();
				services.AddSingleton<ST.WX.MP.WXMPBaseApi>();//todo:微信公众号相关功能应只在统一授权项目中配置，其他项目应删除相关代码
				#endregion

				#region 添加业务service
				services.AddScoped(typeof(IServicePartner), typeof(ServicePartner));

				services.AddScoped(typeof(IServiceFinanceRecv), typeof(ServiceFinanceRecv));
				services.AddScoped(typeof(IServiceFinanceRecvDetail), typeof(ServiceFinanceRecvDetail));
				services.AddScoped(typeof(IServiceFinanceRecvDue), typeof(ServiceFinanceRecvDue));


				services.AddScoped(typeof(IServiceMachining), typeof(ServiceMachining));
				#endregion

				#region 添加系统service
				services.AddScoped(typeof(IServiceSysArea), typeof(ServiceSysArea));
				services.AddScoped(typeof(IServiceSysAttachment), typeof(ServiceSysAttachment));
				services.AddScoped(typeof(IServiceSysAuditLog), typeof(ServiceSysAuditLog));
				services.AddScoped(typeof(IServiceSysBuzRowNum), typeof(ServiceSysBuzRowNum));
				services.AddScoped(typeof(IServiceSysDept), typeof(ServiceSysDept));
				//services.AddScoped(typeof(IServiceSysDuty), typeof(ServiceSysDuty));
				services.AddScoped(typeof(IServiceSysEnumCode), typeof(ServiceSysEnumCode));
				//services.AddScoped(typeof(IServiceSysExpress), typeof(ServiceSysExpress));
				//services.AddScoped(typeof(IServiceSysInvoice), typeof(ServiceSysInvoice));
				services.AddScoped(typeof(IServiceSysLog), typeof(ServiceSysLog));
				services.AddScoped(typeof(IServiceSysModule), typeof(ServiceSysModule));
				services.AddScoped(typeof(IServiceSysModuleAction), typeof(ServiceSysModuleAction));
				services.AddScoped(typeof(IServiceSysModuleService), typeof(ServiceSysModuleService));
				services.AddScoped(typeof(IServiceSysOAuth), typeof(ServiceSysOAuth));
				services.AddScoped(typeof(IServiceSysOrganization), typeof(ServiceSysOrganization));
				services.AddScoped(typeof(IServiceSysRole), typeof(ServiceSysRole));
				services.AddScoped(typeof(IServiceSysRoleAction), typeof(ServiceSysRoleAction));
				services.AddScoped(typeof(IServiceSysSession), typeof(ServiceSysSession));
				services.AddScoped(typeof(IServiceSysTableLog), typeof(ServiceSysTableLog));
				services.AddScoped(typeof(IServiceSysUser), typeof(ServiceSysUser));
				services.AddScoped(typeof(IServiceSysUserAddress), typeof(ServiceSysUserAddress));
				services.AddScoped(typeof(IServiceSysUserBankCard), typeof(ServiceSysUserBankCard));
				services.AddScoped(typeof(IServiceSysUserOAuth), typeof(ServiceSysUserOAuth));
				services.AddScoped(typeof(IServiceSysUserRole), typeof(ServiceSysUserRole));
				#endregion

				#region 添加微信相关
				services.AddScoped(typeof(IServiceWXAppConfig), typeof(ServiceWXAppConfig));
				//services.AddScoped(typeof(IServiceWXLog), typeof(ServiceWXLog));
				//services.AddScoped(typeof(IServiceWXMenu), typeof(ServiceWXMenu));
				services.AddScoped(typeof(IServiceWXSession), typeof(ServiceWXSession));
				services.AddScoped(typeof(IServiceWXTplMsgConfig), typeof(ServiceWXTplMsgConfig));
				services.AddScoped(typeof(IServiceWXTplMsgLog), typeof(ServiceWXTplMsgLog));

				#region 小程序相关
				services.AddScoped(typeof(ST.WX.XCX.SubscribeMsg.WXSubscribeMsgApi), typeof(ST.WX.XCX.SubscribeMsg.WXSubscribeMsgApi));
				#endregion

				#region 公众号相关
				services.AddScoped(typeof(ST.WX.MP.TplMsg.WXTplMsgApi), typeof(ST.WX.MP.TplMsg.WXTplMsgApi));
				services.AddScoped(typeof(ST.WX.MP.Menu.WXMenuApi), typeof(ST.WX.MP.Menu.WXMenuApi));
				#endregion

				#endregion

				#region 添加系统相关
				services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
				services.AddMemoryCache();//添加缓存
				services.AddControllersWithViews().AddMvcOptions(opts =>
				{
					// 自定义模型绑定（Newtonsoft.Json）
					//opts.ModelBinderProviders.Insert(0, new JsonModelBinderProvider());
				}).AddNewtonsoftJson();//取代之前的AddMvc
				services.AddRazorPages();
				//解决中文被编码
				services.AddSingleton(HtmlEncoder.Create(UnicodeRanges.All));

				//配置HTTPS
				//services.AddHttpsRedirection(opts =>
				//{
				//	opts.HttpsPort = 443;
				//	opts.RedirectStatusCode = StatusCodes.Status308PermanentRedirect;
				//});

				services.Configure<SiteConfig>(Configuration.GetSection("SiteConfig"));
				services.AddScoped(typeof(IServiceSysSiteConfig), typeof(ServiceSysSiteConfig));
				#endregion

				#region 添加托管等其他服务
				//services.AddHostedService<HostedServiceApplicationLifetime>();
				//services.Configure<HTConfig>(Configuration.GetSection("HTConfig"));
				//services.AddHostedService<HostedServiceHTRealtime>();
				//services.AddHostedService<HostedServiceHTRecord>();
				//services.AddHostedService<HostedServiceWXRemind>();

				#endregion
			}
			catch (Exception ex)
			{
				throw new Exception("ConfigureServices出错", ex);
			}
		}

		// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
		public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
		{
			try
			{
				//logger.LogInformation("Configure");//todo:日志没有打印出来

				HttpContextHelper.Configure(app.ApplicationServices.GetRequiredService<IHttpContextAccessor>());
				LoggingHelper.LoggerFactory = loggerFactory;

				ForwardedHeadersOptions forwardOpts = new ForwardedHeadersOptions();
				forwardOpts.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
				app.UseForwardedHeaders(forwardOpts);//获取客户端信息

				if (env.IsDevelopment())
				{
					app.UseDeveloperExceptionPage();
				}
				else
				{
					app.UseExceptionHandler(a => a.Run(async context =>
					{
						var feature = context.Features.Get<IExceptionHandlerPathFeature>();
						var exception = feature.Error;
						var result = JsonConvert.SerializeObject(new { r = false, m = exception.Message, code = 500 });
						context.Response.ContentType = "application/json";
						await context.Response.WriteAsync(result);
					}));

					//app.UseExceptionHandler("/sys/common/errorreport");//todo:如果有虚拟目录怎么办，能不能正常跳转
					//app.UseHsts();
				}

				//app.UseHttpsRedirection();//http强制跳转到https

				//StaticFileOptions staticOpts = new StaticFileOptions()
				//{
				//	FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "tools")),
				//	RequestPath = "/tools"
				//};
				//staticOpts.RequestPath = "/tools";
				//var typeProvider = new FileExtensionContentTypeProvider();
				//typeProvider.Mappings.Add(".exe", "application/octect-stream");
				//staticOpts.ContentTypeProvider = typeProvider;
				app.UseStaticFiles();
				//app.UseStaticFiles(staticOpts);

				//app.UseCookiePolicy();//删除此行代码或者改写cookie相关代码，否则cookie写不进去

				app.UseRouting();

				app.UseAuthorization();

				//没有Area使用下面的语句
				app.UseEndpoints(config =>
				{
					config.MapControllerRoute(name: "area", pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
					config.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
				});
			}
			catch (Exception ex)
			{
				throw new Exception("Configure出错", ex);
			}
		}
	}
}
